home *** CD-ROM | disk | FTP | other *** search
- (*===========================================================================*)
- (* Add/Update messages *)
- (* *)
- (* Copyright 1988, 1989, 1990, 1991, 1992 by H. Roy Engehausen. All *)
- (* rights reserved. *)
- (* *)
- (*===========================================================================*)
-
- (*===========================================================================*)
- (* Add current msg to message list *)
- (*===========================================================================*)
-
- PROCEDURE add_msg(fileid : STRING; pass_dupe_bid : BOOLEAN);
-
- VAR
- actions_done : action_msg_type;
- bid_is_dupe : BOOLEAN;
- bid_forced : BOOLEAN;
- buff_add : msg_block_ptr;
- i : INTEGER;
- j : WORD;
- msg_index_current : msg_index_ptr;
- str_ptr : ^STRING;
- t_id : file_name_str;
- t_dest : bb_addr_str;
- temp_file : FILE;
- temp_str : STRING[20];
- temp_type : action_msg_type;
- this_act : action_msg_ptr;
-
- LABEL
- find_next_action;
-
- {$I BBMF2A.PAS}
-
- {$UNDEF DEBUG_HOLD}
- {$UNDEF DEBUG_ACT} (* Used to debug ACTIONs *)
- {$UNDEF DEBUG_TIME} (* Debug timing *)
-
- BEGIN;
-
- (*-----------------------------------------------------------------------*)
- (* Obtain the interrupt lock *)
- (*-----------------------------------------------------------------------*)
-
- get_semaphore(semaphore_interrupts, sem_exclusive, FALSE);
-
- WITH active_tcb^.curr_msg.msg_i_mb DO
- BEGIN;
-
- (*-------------------------------------------------------------------*)
- (* Generate a msg number *)
- (*-------------------------------------------------------------------*)
-
- msg_number := next_msg_no;
- IF msg_no_orig = 0 THEN
- msg_no_orig := msg_number;
-
- INC(next_msg_no);
-
- (*-------------------------------------------------------------------*)
- (* Message number warning *)
- (*-------------------------------------------------------------------*)
-
- IF next_msg_no > 65530 THEN
- BEGIN;
- WRITELN;
- WRITELN;
- WRITELN('You cannot exceed message number 65530. You need to');
- WRITELN('issue a GR command to renumber your messages before');
- WRITELN('adding another message.');
- WRITELN;
- WRITELN;
- RUNERROR(max_msg_number_err);
- END;
-
- IF (next_msg_no > 64500) AND ((next_msg_no AND 7) = 0) THEN
- window_write_critical('MSG>Message numbers exceed 64000 --',
- ' Issue GR command to renumber soon');
-
- (*-------------------------------------------------------------------*)
- (* Build the message file name and erase any old ones *)
- (*-------------------------------------------------------------------*)
-
- STR(msg_number, temp_str);
- t_id := opt_block.msg_file_dir + 'BB' + temp_str + '.MSG';
-
- ASSIGN(temp_file, t_id);
- {$I-}
- ERASE(temp_file);
- {$I+}
- i := IORESULT;
-
- (*-------------------------------------------------------------------*)
- (* Rename the temp file to the right name *)
- (*-------------------------------------------------------------------*)
-
- ASSIGN(temp_file, fileid);
- RENAME(temp_file, t_id);
-
- (*-------------------------------------------------------------------*)
- (* See if user demanded a BID *)
- (*-------------------------------------------------------------------*)
-
- bid_forced := (LENGTH(msg_bid) = 1) AND (msg_bid[1] <= CHR(1));
-
- (*-------------------------------------------------------------------*)
- (* Ok process bid now *)
- (*-------------------------------------------------------------------*)
-
- {$IFDEF DEBUG_TIME}
- WRITE('!');
- {$ENDIF}
-
- IF (msg_bid <> '') AND NOT bid_forced THEN
- BEGIN;
-
- (*---------------------------------------------------------------*)
- (* This is when a bid has been specified already. We add it to *)
- (* The file. If its not a duplicate, make sure the "generated" *)
- (* one is not a duplicate either *)
- (*---------------------------------------------------------------*)
-
- bid_is_dupe := bid_add(msg_bid);
- IF NOT bid_is_dupe THEN
- bid_is_dupe := bid_build_test(@active_tcb^.curr_msg.msg_i_mb);
-
- END
- ELSE
-
- (*---------------------------------------------------------------*)
- (* This is when a bid has not been specified. See if we are to *)
- (* automatically generate one. If so then do it. *)
- (*---------------------------------------------------------------*)
-
- bid_gen;
-
- (*-------------------------------------------------------------------*)
- (* If the bid found or generated is a duplicate, then we put the *)
- (* message in hold (as requested by options smf and the call) *)
- (*-------------------------------------------------------------------*)
-
- IF bid_is_dupe AND (NOT bid_forced)
- AND opt_block.opt_hold_dupe_bid AND (NOT pass_dupe_bid) THEN
- BEGIN;
- IF (msg_flag AND mf_hold) = 0 THEN
- BEGIN;
- msg_flag := msg_flag OR mf_hold;
- msg_reason := message_reason_dupbid;
- END;
- send_message(message_reason_dupbid);
- END;
-
- (*-------------------------------------------------------------------*)
- (* If bulletin then check date *)
- (*-------------------------------------------------------------------*)
-
- IF ((msg_flag AND mf_hold) = 0)
- AND ((msg_type <> mt_private)
- OR ((msg_flag AND mf_fwd_list) <> 0))
- AND (msg_type <> mt_nts)
- AND (msg_dt_orig < (current_day_time - opt_block.b_fwd_stop))
- THEN
- BEGIN;
- msg_flag := msg_flag OR mf_hold;
- msg_reason := message_reason_olddate;
- send_message(message_reason_olddate);
- END;
-
- (*-------------------------------------------------------------------*)
- (* See if user wants some action against it *)
- (*-------------------------------------------------------------------*)
-
- (*-------------------------------------------------------------------*)
- (* Set the distribution list name to nothing *)
- (*-------------------------------------------------------------------*)
-
- t_id := '';
-
- (*-------------------------------------------------------------------*)
- (* Prepare to loop down the action chain *)
- (*-------------------------------------------------------------------*)
-
- {$IFDEF DEBUG_TIME}
- WRITE('@');
- {$ENDIF}
-
- this_act := NIL;
-
- (*-------------------------------------------------------------------*)
- (* If the message is already in hold, skip any hold actions by *)
- (* indicating that the hold has alreay been done *)
- (*-------------------------------------------------------------------*)
-
- IF (msg_flag AND mf_hold) <> 0 THEN
- actions_done := action_msg_hold
- ELSE
- actions_done := 0;
-
- (*-------------------------------------------------------------------*)
- (* Loop down the chain look for our action *)
- (*-------------------------------------------------------------------*)
-
- {$IFDEF DEBUG_ACT}
- trace_data('MF2 Act start', msg_number, NIL, msg_to_at);
- {$ENDIF}
-
- GOTO find_next_action; (*- We save a few instructions by doing this -*)
-
- REPEAT
-
- (*-----------------------------------------------------------------*)
- (* Debugging *)
- (*-----------------------------------------------------------------*)
-
- {$IFDEF DEBUG_ACT}
- trace_data('MF2 ACT1', this_act^.action_type,
- this_act, this_act^.action_info);
- {$ENDIF}
-
- (*-----------------------------------------------------------------*)
- (* Set up temp variables *)
- (*-----------------------------------------------------------------*)
-
- temp_type := this_act^.action_type;
-
- (*-----------------------------------------------------------------*)
- (* If we have previously done an action of the same type, *)
- (* then skip this one *)
- (*-----------------------------------------------------------------*)
-
- IF (temp_type AND actions_done AND action_msg_mask) <> 0 THEN
- GOTO find_next_action;
-
- {$IFDEF DEBUG_ACT}
- trace_data('MF2 ACT2', this_act^.action_type,
- this_act, this_act^.action_info);
- {$ENDIF}
-
- (*-----------------------------------------------------------------*)
- (* Set the flags so we know we did one of this type *)
- (*-----------------------------------------------------------------*)
-
- actions_done := temp_type OR actions_done;
-
- (*-----------------------------------------------------------------*)
- (* If the invert flag is showing then we just ignore the action. *)
- (* This makes us ignore any further actions on this message of *)
- (* the same type *)
- (*-----------------------------------------------------------------*)
-
- IF (temp_type AND action_msg_invert) <> 0 THEN
- GOTO find_next_action;
-
- (*-----------------------------------------------------------------*)
- (* Action is hold, hold_old, or reject (They all set the hold bit *)
- (*-----------------------------------------------------------------*)
-
- IF (temp_type AND action_msg_hold) <> 0 THEN
- BEGIN;
-
- (*-------------------------------------------------------------*)
- (* Skip hold if in review status *)
- (*-------------------------------------------------------------*)
-
- IF (msg_flag AND mf_review) > 0 THEN
- GOTO find_next_action;
-
- (*-------------------------------------------------------------*)
- (* Turn on the hold bit *)
- (*-------------------------------------------------------------*)
-
- msg_flag := msg_flag OR mf_hold;
-
- (*-------------------------------------------------------------*)
- (* Set the proper reason code *)
- (*-------------------------------------------------------------*)
-
- IF (temp_type AND action_msg_reject) <> 0 THEN
- msg_reason := message_reason_shouldr
- ELSE
- IF (temp_type AND action_msg_old) <> 0 THEN
- msg_reason := message_reason_olddate
- ELSE
- msg_reason := message_reason_hold;
-
- (*-------------------------------------------------------------*)
- (* Tell everybody why and leave *)
- (*-------------------------------------------------------------*)
-
- send_message(msg_reason);
- GOTO find_next_action;
-
- END;
-
- (*-----------------------------------------------------------------*)
- (* Action is review *)
- (*-----------------------------------------------------------------*)
-
- IF (temp_type AND action_msg_review) <> 0 THEN
- BEGIN;
-
- (*-------------------------------------------------------------*)
- (* Skip review if in hold status *)
- (*-------------------------------------------------------------*)
-
- IF (msg_flag AND mf_hold) > 0 THEN
- GOTO find_next_action;
-
- (*-------------------------------------------------------------*)
- (* Turn on the review bit *)
- (*-------------------------------------------------------------*)
-
- msg_flag := msg_flag OR mf_review;
-
- (*-------------------------------------------------------------*)
- (* Tell everybody why and leave *)
- (*-------------------------------------------------------------*)
-
- send_message(message_review);
- GOTO find_next_action;
-
- END;
-
- (*-----------------------------------------------------------------*)
- (* Common code for the rest *)
- (*-----------------------------------------------------------------*)
-
- i := LENGTH(this_act^.action_info) + 1;
- str_ptr := ADDR(this_act^.action_info[i]);
-
- (*-----------------------------------------------------------------*)
- (* Action is set distribution file name *)
- (*-----------------------------------------------------------------*)
-
- IF (temp_type AND action_msg_distr) <> 0 THEN
- BEGIN;
-
- {$IFDEF DEBUG_DIST}
- WRITELN('Distribution set to ', str_ptr^);
- DELAY(1000);
- {$ENDIF}
-
- t_id := str_ptr^;
- GOTO find_next_action;
-
- END;
-
- (*-----------------------------------------------------------------*)
- (* Action is change_address *)
- (*-----------------------------------------------------------------*)
-
- IF (temp_type AND action_msg_change) <> 0 THEN
- BEGIN;
-
- (*-------------------------------------------------------------*)
- (* The location of the TO portion of the address has already *)
- (* calculated. If not '=' then move it in *)
- (*-------------------------------------------------------------*)
-
- IF str_ptr^ <> '=' THEN
- msg_to := str_ptr^;
-
- (*-------------------------------------------------------------*)
- (* Calculate the location of the @ portion of the address *)
- (*-------------------------------------------------------------*)
-
- i := i + LENGTH(str_ptr^) + 1;
- str_ptr := ADDR(this_act^.action_info[i]);
-
- (*-------------------------------------------------------------*)
- (* If not '=' then move it in *)
- (*-------------------------------------------------------------*)
-
- IF str_ptr^ <> '=' THEN
- msg_to_at := str_ptr^;
-
- (*-------------------------------------------------------------*)
- (* Calculate the location of the @.portion of the address *)
- (*-------------------------------------------------------------*)
-
- i := i + LENGTH(str_ptr^) + 1;
- str_ptr := ADDR(this_act^.action_info[i]);
-
- (*-------------------------------------------------------------*)
- (* If not '=' then move it in *)
- (*-------------------------------------------------------------*)
-
- IF str_ptr^ <> '=' THEN
- msg_to_h := str_ptr^;
-
- END; (*----- End of CHANGE_ADR ----------------------------------*)
-
- (*-----------------------------------------------------------------*)
- (* Chain to next action *)
- (*-----------------------------------------------------------------*)
-
- find_next_action:
-
- msg_action_check(@active_tcb^.curr_msg, this_act);
-
- UNTIL this_act = NIL; (*----- end of loop thru actions --------------*)
-
- {$IFDEF DEBUG_TIME}
- WRITE('#');
- {$ENDIF}
-
- (*-------------------------------------------------------------------*)
- (* Chain the message information onto the msg chain *)
- (*-------------------------------------------------------------------*)
-
- i := OFS(msg_index_start^.msg_i_mb.msg_subj[1])
- - OFS(msg_index_start^)
- + LENGTH(active_tcb^.curr_msg.msg_i_mb.msg_subj);
- GETMEM(msg_index_current, i);
-
- WITH active_tcb^.curr_msg DO
- BEGIN
-
- IF msg_index_start = NIL THEN
- msg_index_start := msg_index_current
- ELSE
- msg_index_end^.msg_i_next := msg_index_current;
-
- msg_i_last := msg_index_end;
- msg_i_next := NIL;
- msg_i_dis := NIL;
-
- MOVE(active_tcb^.curr_msg, msg_index_current^, i);
-
- msg_index_end := msg_index_current;
-
- END;
-
- END;
-
- (*-----------------------------------------------------------------------*)
- (* Build distribution list -- Pop calls scanned stack as needed *)
- (*-----------------------------------------------------------------------*)
-
- {$IFDEF DEBUG_DIST}
- WRITELN('Distribution call to ', t_id);
- DELAY(1000);
- {$ENDIF}
-
- {$IFDEF DEBUG_TIME}
- WRITE('$');
- {$ENDIF}
-
- build_dis(msg_index_current, t_id);
-
- free_task_mem('CS', TRUE);
-
- (*-----------------------------------------------------------------------*)
- (* Add the msg at the end of the msg file *)
- (*-----------------------------------------------------------------------*)
-
- {$IFDEF DEBUG_TIME}
- WRITE('%');
- {$ENDIF}
-
- WITH msg_index_current^ DO
- BEGIN;
-
- (*-------------------------------------------------------------------*)
- (* Open the msg file *)
- (*-------------------------------------------------------------------*)
-
- RESET(msg_file);
-
- (*-------------------------------------------------------------------*)
- (* Get the file size *)
- (*-------------------------------------------------------------------*)
-
- j := FILESIZE(msg_file);
-
- (*-------------------------------------------------------------------*)
- (* Verify gotten size versus calculated size *)
- (*-------------------------------------------------------------------*)
-
- IF j <> next_record_no THEN
- BEGIN;
-
- (*---------------------------------------------------------------*)
- (* The file sizes do not agree... PANIC *)
- (*---------------------------------------------------------------*)
-
- WRITELN('Next record number computed and actual do not agree');
- WRITELN('Computed =', next_record_no, ' Actual =', j);
- IF next_record_no > j THEN
- j := next_record_no
- ELSE
- next_record_no := j;
-
- END;
-
- (*-------------------------------------------------------------------*)
- (* Position to the proper place *)
- (*-------------------------------------------------------------------*)
-
- msg_i_record := j;
-
- SEEK(msg_file, msg_i_record);
-
- (*-------------------------------------------------------------------*)
- (* Write main record and any distribution list *)
- (*-------------------------------------------------------------------*)
-
- WRITE(msg_file, msg_i_mb);
- INC(next_record_no);
-
- IF (msg_i_mb.msg_flag AND mf_fwd_list) <> 0 THEN
- BEGIN;
-
- {$IFDEF POINT_CHK}
- test_pointer(msg_i_dis);
- {$ENDIF}
-
- buff_add := @msg_i_dis^;
-
- WRITE(msg_file, buff_add^);
-
- INC(next_record_no);
-
- END;
-
- (*-------------------------------------------------------------------*)
- (* CLose up the file *)
- (*-------------------------------------------------------------------*)
-
- CLOSE(msg_file);
-
- END;
-
- {$IFDEF DEBUG_TIME}
- WRITE('^');
- {$ENDIF}
-
- (*-----------------------------------------------------------------------*)
- (* Release the interrupt lock *)
- (*-----------------------------------------------------------------------*)
-
- free_semaphore(semaphore_interrupts);
-
- (*-----------------------------------------------------------------------*)
- (* Put the message info in the tcb *)
- (*-----------------------------------------------------------------------*)
-
- active_tcb^.curr_msg := msg_index_current^;
-
- (*-----------------------------------------------------------------------*)
- (* Count the message *)
- (*-----------------------------------------------------------------------*)
-
- INC(msg_counter_ok);
-
- END;
-
- (*===========================================================================*)
- (* Update a msg record *)
- (*===========================================================================*)
-
- PROCEDURE update_msg (i_ptr : msg_index_ptr);
-
- VAR
- buff_add : msg_block_ptr;
- d_ptr : msg_d_ptr;
- i : INTEGER;
- j : WORD;
-
- BEGIN;
-
- (*-----------------------------------------------------------------------*)
- (* Catch an error *)
- (*-----------------------------------------------------------------------*)
-
- IF i_ptr = NIL THEN
- BEGIN;
- WRITELN('NIL ptr passed to update. Operation ignored');
- EXIT;
- END;
-
- {$IFDEF POINT_CHK}
- test_pointer(i_ptr);
- {$ENDIF}
-
- (*-----------------------------------------------------------------------*)
- (* Obtain the interrupt lock *)
- (*-----------------------------------------------------------------------*)
-
- get_semaphore(semaphore_interrupts, sem_exclusive, FALSE);
-
- WITH i_ptr^, i_ptr^.msg_i_mb DO
- BEGIN;
-
- (*-------------------------------------------------------------------*)
- (* Open the file and set position *)
- (*-------------------------------------------------------------------*)
-
- RESET(msg_file);
-
- (*-------------------------------------------------------------------*)
- (* Get the file size *)
- (*-------------------------------------------------------------------*)
-
- j := FILESIZE(msg_file);
-
- (*-------------------------------------------------------------------*)
- (* Verify gotten size versus calculated size and the position wanted *)
- (*-------------------------------------------------------------------*)
-
- IF (j <> next_record_no) OR (j < msg_i_record) THEN
- BEGIN;
-
- (*---------------------------------------------------------------*)
- (* The file sizes do not agree... PANIC *)
- (*---------------------------------------------------------------*)
-
- WRITELN;
- WRITELN('Next record number computed and actual do not agree');
- WRITELN('or seek malfunction');
- WRITELN('Computed =', next_record_no, ' Actual =', j,
- ' Seek =', msg_i_record);
- WRITELN;
- RUNERROR(msg_runerr);
-
- END;
-
- (*-------------------------------------------------------------------*)
- (* Set Position *)
- (*-------------------------------------------------------------------*)
-
- SEEK(msg_file, msg_i_record);
-
- (*-------------------------------------------------------------------*)
- (* Update the primary record *)
- (*-------------------------------------------------------------------*)
-
- WRITE(msg_file, msg_i_mb);
-
- (*-------------------------------------------------------------------*)
- (* If a distribution list is present, update it too! *)
- (*-------------------------------------------------------------------*)
-
- IF (msg_i_mb.msg_flag AND mf_fwd_list) <> 0 THEN
- BEGIN;
-
- (*---------------------------------------------------------------*)
- (* Find the distribution block pointer. See if routing block *)
- (* is present *)
- (*---------------------------------------------------------------*)
-
- IF (msg_i_mb.msg_flag AND mf_disrout) <> 0 THEN
- BEGIN;
- {$IFDEF POINT_CHK}
- test_pointer(msg_i_dr);
- {$ENDIF}
- d_ptr := msg_i_dr^.msg_dr_dblk
- END
- ELSE
- d_ptr := msg_i_dis;
-
- (*---------------------------------------------------------------*)
- (* Is the distribution block present? If not don't update *)
- (*---------------------------------------------------------------*)
-
- IF d_ptr <> NIL THEN
- BEGIN;
-
- {$IFDEF POINT_CHK}
- test_pointer(d_ptr);
- {$ENDIF}
-
- (*-----------------------------------------------------------*)
- (* Get number of items in the array *)
- (*-----------------------------------------------------------*)
-
- i := d_ptr^.msg_d_no;
-
- (*-----------------------------------------------------------*)
- (* Validate *)
- (*-----------------------------------------------------------*)
-
- IF i > msg_dist_max THEN
- BEGIN;
- WRITELN('MF2 Invalid distribution # -- ', i ,
- ' -- # ', msg_i_mb.msg_number);
- dump_reason('Invalid distribution # MF2');
- dump_trace;
- dump_msg(i_ptr);
- RUNERROR(msg_runerr);
- END;
-
- (*-----------------------------------------------------------*)
- (* Write the record out *)
- (*-----------------------------------------------------------*)
-
- buff_add := ADDR(d_ptr^);
-
- WRITE(msg_file, buff_add^);
-
- END;
-
- END; (*----- End distribution list update -------------------------*)
-
- (*-------------------------------------------------------------------*)
- (* Done with the file! *)
- (*-------------------------------------------------------------------*)
-
- {$I-}
- CLOSE(msg_file);
- {$I+}
- i := IORESULT;
-
- (*-------------------------------------------------------------------*)
- (* Release the interrupt lock *)
- (*-------------------------------------------------------------------*)
-
- free_semaphore(semaphore_interrupts);
-
- END;
-
- (*-----------------------------------------------------------------------*)
- (* Count the messages *)
- (*-----------------------------------------------------------------------*)
-
- count_msg_list;
-
- END;